package scenic.rd_english;


import org.hibernate.Session;
import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;
import org.junit.Test;

import javax.persistence.*;
import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.regex.Pattern.CASE_INSENSITIVE;

/**
 * Created by scenic on 2018/1/2.
 */
public class RDEnglishMain {
    public static void main(String args[]) {
        RDEnglishMain m = new RDEnglishMain();
        if (args.length == 0) {
            Set<Lesson> allContent = m.getAllContent();
            m.saveToDB(allContent);
            System.out.println("update the database");
        } else {
            m.findKey(args[0]);
        }

    }

    private String highlight(String v) {
        return "\033[31;4m" + v + "\033[0m";
    }

    private void findKey(String keyWord) {
        Session session = getSessionFactory().openSession();
        session.beginTransaction();
        //noinspection JpaQlInspection
        String url = "from Lesson l where l.context like ?";
        List<Lesson> resultFromDB = session.createQuery(url).setParameter(0, "%" + keyWord + "%").list();
        session.getTransaction().commit();
        session.close();

        Map<String, String> result = new HashMap<>();

        resultFromDB.forEach(lesson -> result.put(lesson.title + ":" + lesson.book.getName(), lesson.context));

        result.forEach((title, content) -> {
            Pattern pattern = Pattern.compile(".*(" + keyWord + ").*", CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(content);
            Set<String> set = new HashSet<>();
            while (matcher.find()) {
                set.add(matcher.group(1));
            }

            final String[] print = {content};
            set.forEach(willBeReplaced -> print[0] = print[0].replaceAll(willBeReplaced, highlight(willBeReplaced)));

            System.out.println(title);
            System.out.println(print[0]);
        });

    }

    private SessionFactory getSessionFactory() {
        Configuration configuration = new Configuration();
        SessionFactory factory = configuration.configure(getClass().getClassLoader().getResource("hibernate.cfg.xml"))
                .buildSessionFactory();
        return factory;
    }

    private void saveToDB(Set<Lesson> allContent) {

        Session session = getSessionFactory().openSession();
        session.beginTransaction();
        allContent.forEach(book -> session.saveOrUpdate(book));

        session.getTransaction().commit();
        session.close();

    }

    private Set<Lesson> getAllContent() {
        String path = this.getClass().getClassLoader().getResource("nce").getPath();

        File[] files = new File(path).listFiles();

        Set<Lesson> lessons = new HashSet<>();

        Arrays.asList(files).forEach(bookPath -> {

            if (!bookPath.isDirectory()) {
                return;
            }

            String bookString = bookPath.toString();
            Book book = new Book();
            book.name = bookString.substring(bookString.length() - 1);
            Arrays.asList(bookPath.listFiles()).forEach(whichLesson -> lessons.add(createLesson(whichLesson, book)));

        });

        return lessons;

    }

    public Lesson createLesson(File lessonPath, Book book) {
        try {
            String lessonTitle = lessonPath.toString();
            lessonTitle = lessonTitle.substring(lessonTitle.lastIndexOf("\\") + 1);
            lessonTitle = lessonTitle.substring(0, lessonTitle.lastIndexOf("."));
            Lesson lesson = new Lesson();
            lesson.setTitle("lesson " + lessonTitle);
            lesson.setBook(book);

            FileInputStream inputStream = new FileInputStream(lessonPath);
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "gbk"));
            String tmp;
            StringBuffer stringBuffer = new StringBuffer();
            while ((tmp = reader.readLine()) != null) {
                stringBuffer.append(tmp).append("\r\n");
            }
            lesson.setContext(stringBuffer.toString());
            return lesson;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Entity(name = "Lesson")
    public static class Lesson {
        @Id
        @GeneratedValue
        private int id;
        String title;
        @Column(name = "context", length = 2555)
        String context;
        @ManyToOne(cascade = CascadeType.ALL)
        Book book;

        public void setId(int id) {
            this.id = id;
        }

        public int getId() {
            return id;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getTitle() {
            return title;
        }

        public void setContext(String context) {
            this.context = context;
        }

        public String getContext() {
            return context;
        }

        public void setBook(Book book) {
            this.book = book;
        }

        public Book getBook() {
            return book;
        }
    }

    @Entity(name = "Book")
    public static class Book {
        @Id
        @GeneratedValue
        private int id;
        private String name;


        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

    }
}
